-- region SceneManager.lua
-- Author : Bingle
-- Date   : 2015/3/11
-- Description ：场景管理器 
require 'waitingnet'
require "comm/ServerDataModel"
require "common/StateMachine.lua"
require "common/ModalDlgManager.lua"
-- 场景背景半透明值(0-256)
local SCENE_HALF_OPACITY = 128

SceneManager = class("SceneManager",function()
        local obj = {

            -- 所有场景，其中arrLayers为所有层，
            -- 每层的结构是：
            -- {
            --   layer = layer -- layer对象
            --   arrViews = {}    -- 该层上的所有视图对象
            -- }
            arrAllScenes = {   
                scene = nil,
                control = nil,
                arrLayers = nil,
            },

            dicLaterScene = nil,
            -- 保存的主场景
            arrSavedMainScene = nil,
            -- 保存玩家等级
            nSavedLevel = nil,
            -- 保存通关关卡
            nSavedOpenBattleId = nil,
            nSavedOpenChapterId = nil, 
            -- 函数定义

            -- 创建场景管理器
            create = function()end,
            -- 获取单例
            ins = function()end,
            -- 初始化函数
            init = function()end,
            -- 切换场景，并播放场景背景音乐
            switchScene = function(objScene,sSceneName,control)end,
            -- 恢复主城场景
            restoreMainScene = function()end,
            -- 压入场景,仅供内部调用
            pushScene = function(objScene,sSceneName)end,
            -- 弹出当前场景,仅供内部调用
            popScene = function()end, 
            -- 停止当前全屏业务模块
            stopModule = function()end,
            -- 在当前场景添加一个视图对象
            addView = function(classView)end,
            -- 移除当前场景顶层的视图对象
            removeView = function(objView)end, 
            -- 获取当前场景
            getScene = function()end,
            -- 获取当前场景的底层
            getBottomLayer = function()end,
            -- 获取当前场景的顶层
            getTopLayer = function()end,
            -- 拷屏场景为一个sprite
            sceneToSprite = function()end,
            -- 添加调试按钮，点击按钮将输出纹理占用内存情况
            addDebugButton = function()end,
            -- 在场景中加入单个节点，该节点不纳入管理体系
            addToScene = function(objNode)end,
            -- 注册按键响应
            registEventListenerKeyboard = function(objScene)end,
            -- 使得UI组件在屏幕自适应时靠左对齐(UI组件在设计时按1136X640摆放)
            alignToLeft_1136X640 = function(node)end,
            -- 使得UI组件在屏幕自适应时靠右对齐(UI组件在设计时按1136X640摆放)
            alignToRight_1136X640 = function(node)end,
            -- 使得UI组件在屏幕自适应时靠左对齐(UI组件在设计时按960X640摆放)
            alignToLeft_960X640 = function(node)end,
            -- 使得UI组件在屏幕自适应时靠右对齐(UI组件在设计时按960X640摆放)
            alignToRight_960X640 = function(node)end,
			--视图边界组件如上下左右的控件数组
			arrEdge={},
        }
        return obj
    end)
SceneManager.__index = SceneManager

-- 单例设计
SceneManager.__instance = nil

-- 创建场景管理器
function SceneManager:create() 
    local obj = SceneManager:new() 
    obj:init()
    SceneManager.__instance = obj 
    return obj
end

-- 获取单例
function SceneManager:ins()
    if nil == SceneManager.__instance then
        SceneManager.__instance = SceneManager:create()
		SceneManager.__instance:init()
    end
    return SceneManager.__instance
end

-- 初始化函数
function SceneManager:init()
end

function SceneManager:backToLogin()
	tcpnet.clearnet();
    tcpnet.resetLoginState();
	 for _,sceneItem in pairs(self.arrAllScenes)do
        print("name=",sceneItem.state.name,sceneItem.control.stop)
		if sceneItem.control.stop ~= nil then
			sceneItem.control:stop()
		end
		local aryRes = sceneItem.state.aryRes or {}
		local arrlen=#aryRes
		for k=1,arrlen do 
			print(sceneItem.state.name .. "返回登录后释放" .. aryRes[k] .. ".plist")
			removePlist(aryRes[k] .. ".plist")
		end 
     end 
    LoginControl:create():start()
    --DataManager:ins():reloadData()
end
-- 切换场景，并播放场景背景音乐
function SceneManager:switchScene(objScene,sSceneName,control) 
	userop.userop("切换到场景到" .. sSceneName)
    local ccScene = cc.Scene:create() 
    local sMusicFile = string.format("res/sound/bgMusic%s.m4a",sSceneName)
    objScene:setPosition(WINDOW_CENTER)
    print("切换到场景",sSceneName,#self.arrAllScenes)
    ccScene:addChild(objScene)
    local director = cc.Director:getInstance()
	if 0 == #self.arrAllScenes then 
        director:replaceScene(ccScene)  
        AudioEngine.playMusic(SoundDataManager:ins():getSoundPath(1),true)
    else
        if self.arrAllScenes[1] ~= nil and self.arrAllScenes[1].state.name == "MainScene" and sSceneName == "BattleScene" then
			--table.remove(self.arrAllScenes,#self.arrAllScenes) 
            self.arrSavedMainScene = self.arrAllScenes
            self.nSavedLevel = PlayerData.player_login_data.base.level
            self.nSavedOpenBattleId = ChapterData.battle_open.open_battle_id
            self.nSavedOpenChapterId = ChapterData.battle_open.open_chapter_id
            for _,sceneItem in ipairs(self.arrAllScenes)do 
                if sceneItem.control.save ~= nil then
                    sceneItem.control:save()
                end
                if sceneItem.control.stop ~= nil then
                    sceneItem.control:stop()
                end
				local aryRes = sceneItem.state.aryRes or {}
				local arrlen=#aryRes
				for k=1,arrlen do 
					print(sceneItem.state.name .. "进入战斗后释放" .. aryRes[k] .. ".plist")
					removePlist(aryRes[k] .. ".plist")
				end 
            end
            Comm:ins():unregistAllNotify()
        end
		director:popToRootScene() 
        director:pushScene(ccScene) 
    end  
	local layer = objScene:getLayer() 
	local dicScene = 
	{ 
		state = {name=sSceneName},
		scene = objScene,
		control = control,
		arrLayers =  
		{ 
			{layer = layer,arrViews = {} },
		}, 
	}  
	ccScene.dicScene=dicScene 
    self.arrAllScenes={dicScene}
	self:registerScene(ccScene)
	
	if nil ~= ServerDataModel.ins()then
		ServerDataModel.ins():dealNotice(SCENE_SWITCH_NOTIFY)
	end

	--self:debugMemeory(1,sSceneName)  
    self:addLayers()	
    --pts('switch')
end  
-- 恢复主城场景
function SceneManager:restoreMainScene()
	--- 
    AudioEngine.playMusic(SoundDataManager:ins():getSoundPath(1),true)
    if self.arrSavedMainScene ~= nil then  
		for _,sceneItem in ipairs(self.arrSavedMainScene)do 
			local aryRes = sceneItem.state.aryRes or {}
			local arrlen=#aryRes
			for k=1,arrlen do 
			   addPlist(aryRes[k] .. ".plist")
			end 
		end	 
		local main = MainControl:create()
        main:start() 
        if #self.arrSavedMainScene >= 2  then 
            local state = self.arrSavedMainScene[#self.arrSavedMainScene].state 
			local control=self.arrSavedMainScene[#self.arrSavedMainScene].state.control:create() 
            self:pushScene(state,control) 
			if state.mainTop then  
				control.mainTopControl = MainTopControl:create()
				control.mainTopControl:start()
			end			
            control:start() 
		end
	    
        self:addLayers()
        if self.nSavedLevel ~= PlayerData.player_login_data.base.level then  
			DataManager:ins():notifyDataChanged(PLAYER_LEVEL_UP_NOTIFY,PlayerData.player_login_data.base.level) 
        end
        if self.nSavedOpenChapterId ~= ChapterData.battle_open.open_chapter_id then  
			DataManager:ins():notifyDataChanged(CHAPTER_OPEN_NOTIFY,{ ChapterData.battle_open.open_battle_id,ChapterData.battle_open.open_chapter_id })
        end   
    end 
end
--回到根场景 
function SceneManager:popToRoot()
	print("移动到根部节点=",#self.arrAllScenes)
    while #self.arrAllScenes > 1 do 
		self:removeStack() 
    end
end
--场景入栈  
function SceneManager:pushScene(state,control,isreplace) 
	local dicScene=self.arrAllScenes[#self.arrAllScenes]
    if dicScene.control.endGuide then
		dicScene.control:endGuide() 
    end 
	if GuideView.ins()~=nil then GuideView.ins():changeSceneEvent() end
	if GuideStoryView.ins()~=nil then GuideStoryView.ins():changeSceneEvent() end

	local objLayer = cc.Layer:create()
	local objMask = cc.LayerColor:create() 
	local createScene = function()
		return TuiBase:create()
	end 
	REGISTER_SCENE_FUNC(state.name,createScene) 
	local objScene = LoadScene(state.name)
	objMask:setColor(cc.c3b(0,0,0)); 
	objMask:setOpacity(SCENE_HALF_OPACITY); 
	objMask:setContentSize(REAL_SCREEN_SIZE)
	objMask:ignoreAnchorPointForPosition(false)
	objMask:setAnchorPoint(0.5,0.5)
	objLayer:addChild(objMask) 
	objScene:setPosition(WINDOW_CENTER)
	objScene:addChild(objLayer)
	objScene.objLayer = objLayer
	objScene.getLayer = function(obj) return obj.objLayer end 
	local dicScene = 
	{ 
		state = state,
		scene = objScene,
		control = control, 
		arrLayers = 
		{ 
			{
				layer = objLayer,
				arrViews = {}
			},
		},
	}
    local ccScene = cc.Scene:create()
    ccScene:addChild(objScene)
	ccScene.dicScene=dicScene
	if isreplace then  
		local preDicScene=self.arrAllScenes[#self.arrAllScenes]
		if preDicScene.control.stop then
			preDicScene.control:stop() 
		end 
		self.arrAllScenes[#self.arrAllScenes]=dicScene	
		cc.Director:getInstance():replaceScene(ccScene)
	else
        waitingnet.clear()--一定要把菊花清理掉，否则会出现任务面板的任务列表到来后菊花从A界面创建，却又在B界面去判断到来后的移除，
		table.insert(self.arrAllScenes,dicScene)	
		cc.Director:getInstance():pushScene(ccScene)
	end
	self:registerScene(ccScene) 
    self:addLayers() 
end



--锁屏
function SceneManager:lockScreen()
	--要加上一个禁止触摸层
	local scene=self.arrAllScenes[#self.arrAllScenes].scene
	local dlg= ModalDlgManager:ins():createDlg()  
	scene:addChild(dlg,22222222) 
	local delay=cc.DelayTime:create(0.5)
	local call=cc.CallFunc:create(function() dlg:removeFromParent() end)
	dlg:runAction(cc.Sequence:create(delay,call))
end



function SceneManager:registerScene(ccScene)  
	local function eventfun(event) 
		if event == "enterTransitionFinish" then 
			cc.Director:getInstance():getTextureCache():removeUnusedTextures()
			local dicScene=self.arrAllScenes[#self.arrAllScenes] 
			if dicScene.state.mainTop then  
				--对场景视图做动画  
				local objLayer=dicScene.arrLayers[1].arrViews[1] 
				if objLayer then 
					objLayer:setScale(0.99)
					local s1=cc.ScaleTo:create(0.1,1.01) 
					local s2=cc.ScaleTo:create(0.1,1)  
					objLayer:runAction(cc.Sequence:create(s1,s2))
				end
				--要加上一个禁止触摸层
				self:lockScreen()
			end  
			self:registEventListenerKeyboard(ccScene) 
		end
	end 
	regNodeEvent(ccScene,eventfun); 
end
function SceneManager:gotoPreScene()
	local dicScene=self.arrAllScenes[#self.arrAllScenes]  
	local aryRes=dicScene.state.aryRes or {} 
	local arrlen=#aryRes
	userop.userop("切换到前一个场景")
	print("前一个场景名称是" .. dicScene.state.name .. "释放的资源长度为" .. arrlen) 
	if dicScene.control.stop then 
		dicScene.control:stop()
	end  	
	for k=1,arrlen do 
		removePlist(aryRes[k] .. ".plist")
	end 
	cc.Director:getInstance():popScene() 
	table.remove(self.arrAllScenes,#self.arrAllScenes)--移除栈顶 
	if #self.arrAllScenes > 1 then 
		self:addLayers()  
		DataManager:ins():notifyDataChanged(EVENT_LISITEN_POP,nil) 
		package.loaded["src/common/PublicFunction"] = nil
		package.loaded["common/PublicFunction"] = nil
		require "common/PublicFunction"
		PublicFunction:reloadLua()  
    end	
end
-- 弹出当前场景,仅供内部调用
function SceneManager:popScene()   
	self:playBackMoive(function() self:gotoPreScene() end)
end 
--播放菜单栏收回动作
function SceneManager:playBackMoive(playEnd)
	--要加上一个禁止触摸层
	self:lockScreen()  
	if #self.arrEdge > 0 then 
		local function endcb() 
			playEnd()
		end 
		for key,value in pairs(self.arrEdge) do 
            if value.back then 	
				value:back(endcb)  
			end
		end
	else 
		playEnd() 
    end
end
function SceneManager:gotoState(state,setDataFunc,isreplace)
    userop.userop("切换到场景到" .. state.name) 
	setDataFunc = setDataFunc or function()end
	local control = state.control:create() 
	self:pushScene(state,control,isreplace)  
	setDataFunc(control) 
	if state.mainTop then  
		control.mainTopControl = MainTopControl:create()
		control.mainTopControl:start()
	end
	control:start() 
end 
--是否替换当前状态isreplace
function SceneManager:setState(state,setDataFunc,isreplace)
	if not state then 
		print("当前状态未注册状态机")
		return
	end
	isreplace = isreplace or false
	print("状态机当前状态",state.name) 
	print("状态机长度=",#self.arrAllScenes)
    local dicScene = self.arrAllScenes[#self.arrAllScenes] 
    if state.name == dicScene.state.name then 
		print("状态机重复执行统一状态",state.name)
	    return
	end
	if state.openstate then 
		local opened,_ = DataManager:ins():getOpenState(state.openstate[1],true)
		if not opened then 
			return
		end
	end
	local function isInArr(state)
		--判断是否是互斥的场景，防止场景无限制增加	
		local sarr = {StateMachine.s_Vip,StateMachine.s_Task,StateMachine.s_Friend} 
		for key,value in pairs(sarr) do  
			if value.name == state.name then 
				return true
			end
		end
		return false
	end 
	local nextIsTopState=isInArr(state) 
	local curIsTopState=isInArr(dicScene.state) 
	if nextIsTopState and curIsTopState then  
		isreplace=true 
	end	
	--异步加载完资源的回调
	local function resDidLoaded()
        --先判断是否需要做收回顶部底部或左右的菜单 
		if GuideView.ins()~=nil then  GuideView.ins():changeSceneEvent()end  
		if GuideStoryView.ins()~=nil then  GuideStoryView.ins():changeSceneEvent()end 
		self:playBackMoive(function() self:gotoState(state,setDataFunc,isreplace) end) 
	end      
	local arrlen=#state.aryRes 
	print("场景" .. state.name .. "加载的资源长度为" .. arrlen) 
	local loadcnt=0
    --要加上一个禁止触摸层
	self:lockScreen()	
	for i=1,arrlen do  
		 local function everyFinishFunc()
			--因为多线程可能返回的顺序和预期不一致，所以只能使用累加器
			loadcnt=loadcnt+1 
			addPlist(state.aryRes[i] .. ".plist") 
            if loadcnt>=arrlen then 
				--如果全部加载完plist就执行场景加载
			    resDidLoaded()	
            end
        end  
		--这种写法是利用手机多核来优化资源加载 
		cc.Director:getInstance():getTextureCache():addTextureAsync(state.aryRes[i] .. ".pvr.ccz",everyFinishFunc) 
    end 
	if arrlen <= 0 then 
		resDidLoaded()
	end
end 
--移除栈信息
function SceneManager:removeStack() 
    local dicScene=self.arrAllScenes[#self.arrAllScenes] 
	local aryRes=dicScene.state.aryRes or {} 
	local arrlen=#aryRes
	print("前一个场景名称是" .. dicScene.state.name .. "释放的资源长度为" .. arrlen) 
	if dicScene.control.stop then 
		dicScene.control:stop()
	end  	
	for k=1,arrlen do 
		removePlist(aryRes[k] .. ".plist")
	end 
	cc.Director:getInstance():popScene() 
	table.remove(self.arrAllScenes,#self.arrAllScenes)--移除栈顶	
end
-- 停止当前全屏业务模块
function SceneManager:stopModule() 
    -- 判断是否已经没有场景关联模块 
    if 0 == #self.arrAllScenes then
		print("stopModule没有任何场景列表")
        return
    end 
    
    local dicScene = self.arrAllScenes[#self.arrAllScenes] 
    if dicScene.control.stop then
		dicScene.control:stop() 
    end   
    if GuideView.ins()~=nil then GuideView.ins():changeSceneEvent()end  
    if GuideStoryView.ins()~=nil then GuideStoryView.ins():changeSceneEvent() end
 
    self:popScene()  
 
    if DataManager.__instance then
        DataManager:ins():notifyDataChanged(EVENT_LISITEN_POP,nil)
    end

 
end

-- 停止缓存的模块
function SceneManager:stopCachedModule() 
    -- 判断是否已经没有场景关联模块
    if 0 == #self.arrAllScenes then
        return
    end
    local dicScene = self.dicLaterScene
    -- 执行模块的停止函数
    if nil ~= dicScene.control and nil ~=dicScene.control.stop then
        dicScene.control:stop()
        --log.debug("SceneManager:stopModule","成功停止模块%s。",dicScene.control.__cname)
    end
    if dicScene.scene ~= nil then
        self:popScene()
    end
    self.dicLaterScene = nil 
    DataManager:ins():notifyDataChanged(EVENT_LISITEN_POP,nil)
----------------------------------------------
-- 每次推出场景，就重新加载一些必要场景。
    package.loaded["src/common/PublicFunction"] = nil
    package.loaded["common/PublicFunction"] = nil
    require "common/PublicFunction"
    PublicFunction:reloadLua() 
end 

-- 在当前场景添加一个视图对象
function SceneManager:addView(classView,layer) 
    local dicScene=self.arrAllScenes[#self.arrAllScenes] 
    if self.dicLaterScene ~= nil then 
        dicScene = self.dicLaterScene
    end
    local objView = classView:create()
    local dicLayer = dicScene.arrLayers[#dicScene.arrLayers] 
    -- zjb 暂时这样改吧！以后要改过来
    dicLayer.layer:addChild(objView,layer=='hud' and 1 or 0)
    table.insert(dicLayer.arrViews,objView) 
    return objView
end 

-- 移除当前场景顶层的视图对象
function SceneManager:removeView(objView) 
    local dicScene=self.arrAllScenes[#self.arrAllScenes] 
    local arrLayers = dicScene.arrLayers
    local dicLayer = arrLayers[#arrLayers]
    if dicLayer ~= nil then
        for i,view in ipairs(dicLayer.arrViews)do
            if view == objView then
                view:removeFromParent(true)
                table.remove(dicLayer.arrViews,i)
                break
            end
        end
    end
end 
-- 获取当前场景
function SceneManager:getScene() 
	if 0 == #self.arrAllScenes then
        return nil
    end 
    if self.arrAllScenes[#self.arrAllScenes].scene == nil then
        return self.arrAllScenes[#self.arrAllScenes -1].scene
    end
    return self.arrAllScenes[#self.arrAllScenes].scene
end
-- 获取当前场景的底层
function SceneManager:getBottomLayer() 
    if 0 == #self.arrAllScenes then
        return nil
    end
	local dicScene=self.arrAllScenes[#self.arrAllScenes] 
    local arrLayers = dicScene.arrLayers
    if 0 == #arrLayers then
        return nil
    end
    return arrLayers[1].layer
end

-- 获取当前场景的顶层
function SceneManager:getTopLayer() 
   if 0 == #self.arrAllScenes then
        return nil
    end
    local dicScene=self.arrAllScenes[#self.arrAllScenes] 
    local arrLayers = dicScene.arrLayers
    if 0 == #arrLayers then
        return nil
    end
    return arrLayers[#arrLayers].layer
end 

-- 拷屏场景为一个sprite
function SceneManager:sceneToSprite()
    return cc.utils:captureScreenAsSprite()
end 
-- 添加调试按钮，点击按钮将输出纹理占用内存情况
function SceneManager:addDebugButton()
    if DEBUG_VERSION then
        local objScene = self:getScene()
        if self.panel_dump then
            changeParent(self.panel_dump,objScene)
            moveToFirst(self.panel_dump)
        else
            self.panel_dump = TuiManager:getInstance():createPanel(1,0,0,0,0,0)
            self.btn_dump = TuiManager:getInstance():createBtn(
                    0,
                    cc.c3b(255,255,255),
                    24,
                    DEFAULT_TTF_PATH,
                    "内存测试",
                    "res/public/button/btn_blue_a_normal.png",
                    nil,
                    nil,
                    0,
                    0,
                    141,
                    55,
                    0,
                    1
				)
            self.panel_dump:retain()
            self.btn_dump:retain()
            self.btn_dump : getLabel(): setStyle(1)
            self.btn_dump :setOnClickScriptHandler(function()
                    pts('test')
                    --log.debug("HomeScene:init",cc.Director:getInstance():getTextureCache():getCachedTextureInfo())
                end)
            self.btn_dump:setName("btn_dump")
            self.panel_dump:addChild(self.btn_dump)
            objScene:addChild(self.panel_dump,1000)
            self.btn_dump:setOpacity(75)
        end
        local dbbtn_x = cc.UserDefault:getInstance():getStringForKey("dbbtn_x")
        local dbbtn_y = cc.UserDefault:getInstance():getStringForKey("dbbtn_y")
        if dbbtn_x == '' then 
            dbbtn_x = 300
        else
            dbbtn_x = tonumber(dbbtn_x)
        end
        if dbbtn_y == '' then 
            dbbtn_y = 260
        else
            dbbtn_y = tonumber(dbbtn_y)
        end
        self.panel_dump:setPosition(cc.p(dbbtn_x,dbbtn_y))
        self.btn_dump:setScale(0.75)
        
        --[
        local listener = cc.EventListenerTouchOneByOne:create()
        local tx,ty
        
        listener:registerScriptHandler(function(touch,event)
            if self.panel_dump:getReferenceCount()==0 then
                return false
            end
            local pos1 = touch:getLocation()
            --local tx,ty = globalPointToLocal(pos1.x,pos1.y,self.btn_dump)
            local p = self.panel_dump:convertToNodeSpace(pos1)
            tx,ty = p.x,p.y
            local bb = self.btn_dump:getBoundingBox()
            local point = self.btn_dump:convertToNodeSpace(cc.p(pos1.x,pos1.y))
            return(tx>=bb.x)and(ty>=bb.y)and(tx<=(bb.x+bb.width))and(ty<=(bb.y+bb.height))
         end,cc.Handler.EVENT_TOUCH_BEGAN) 
        listener:registerScriptHandler(function(touch,event)
            local pos1 = touch:getLocation()
            local pos2x,pos2y = objScene:getPosition()
            self.panel_dump:setPosition(cc.p(pos1.x-pos2x-tx,pos1.y-pos2y-ty))
            return true
         end ,cc.Handler.EVENT_TOUCH_MOVED)
        listener:registerScriptHandler(function(touch,event)
            
            dbbtn_x,dbbtn_y = self.panel_dump:getPosition()
            cc.UserDefault:getInstance():setStringForKey("dbbtn_x",string.format('%d',dbbtn_x))
            cc.UserDefault:getInstance():setStringForKey("dbbtn_y",string.format('%d',dbbtn_y))
            cc.UserDefault:getInstance():flush()
            return true
         end ,cc.Handler.EVENT_TOUCH_ENDED)
        local eventDispatcher = self.btn_dump:getEventDispatcher()
        eventDispatcher:addEventListenerWithSceneGraphPriority(listener,self.btn_dump) 
    end  
end 
-- 内存调试
function SceneManager:debugMemeory(nType,sSceneName) 
    if not DEBUG_VERSION then
        return 
    end
    local dumpString = cc.Director:getInstance():getTextureCache():getCachedTextureInfo()
    local arrMemInfos = string.split(dumpString,"\n")
    local memoInfo = { items = {},count = 0,size = 0 }
    for _,item in ipairs(arrMemInfos)do 
        local nStart,nLength,str1,str2 = string.find(item,"(.*)/res(.*)\".*")
        if  str1 ~= nil and str2 ~= nil then 
            memoInfo.items["/res"..str2] = 1
        else 
            local _,_,n1,n2 = string.find(item,"TextureCache.+(%d+).+(%d+).+")
            if n1~=nil and n2 ~= nil then 
                memoInfo.count = n1
                memoInfo.size = n2
            end
        end 
    end
    if nType == 1 and sSceneName == "MainScene" and self.memoInfo == nil then 
        self.memoInfo = memoInfo
        log.debug("debugMemeory","内存中纹理个数 %d 个,总计大小 %d KB:",self.memoInfo.count,self.memoInfo.size)
        for _,item in ipairs(DataManager:ins():getKeys(memoInfo.items))do 
            log.debug("debugMemeory",item)
        end        
    elseif self.memoInfo ~= nil then
        -- and #self.arrAllScenes == 1 
        -- and self.arrAllScenes[1].name == "MainScene" 
        

        log.debug("debugMemeory","内存中纹理个数多出 %d 个,总计大小多出 %d KB:",memoInfo.count - self.memoInfo.count,memoInfo.size - self.memoInfo.size)
        for _,item in ipairs(DataManager:ins():getKeys(memoInfo.items))do 
            if self.memoInfo.items[item] == nil then 
                log.debug("debugMemeory",item)
            end
        end
    end
end
--层排列顺序
--退出层
--弹出层
--引导层
--HUD层
--场景层
_layerOrder = {'hud_layer','popup_layer','guide_layer','model_layer','wait_layer','exit_layer'}

function SceneManager:saveLayers()
    for _,name in ipairs(_layerOrder) do
        local tdl = self[name]
        if tdl then
            tdl:removeFromParent(false)
        end
    end
end

--为一个新的场景添加一系列的层
function SceneManager:addLayers()
    --pts('fire addLayers')
    local objScene = self:getScene() 
    for _,name in ipairs(_layerOrder) do
        --如果添加过了就不添加了
        if objScene:getChildByName(name) then 
            break
        end
        tdl = cc.LayerColor:create()
        tdl:setName(name)
        objScene:addChild(tdl)
    end
	if DEBUG_VERSION then
		self:addDebugButton()
	end
end


function SceneManager:_addToSpecificLayer(name,objNode)
    local objScene = self:getScene()
    local layer = objScene:getChildByName(name)
    assert(layer)
    layer:addChild(objNode)
end
function SceneManager:getExitLayer()
	local objScene = self:getScene() 
    local layer = objScene:getChildByName('exit_layer')
	return layer;
end

function SceneManager:getWaitLayer()
	local objScene = self:getScene()
    local layer = objScene:getChildByName('wait_layer')
	return layer;
end

function SceneManager:addToExitLayer(objNode)
    self:_addToSpecificLayer('exit_layer',objNode)
end

function SceneManager:addToGuideLayer(objNode)
    self:_addToSpecificLayer('guide_layer',objNode)
end

function SceneManager:addToPopupLayer(objNode)
    self:_addToSpecificLayer('popup_layer',objNode)
end

function SceneManager:addToHudLayer(objNode)
    self:_addToSpecificLayer('hud_layer',objNode)
end

function SceneManager:addToModelLayer(objNode)
    self:_addToSpecificLayer('model_layer',objNode)
end

function SceneManager:addToWaitLayer(objNode)
    self:_addToSpecificLayer('wait_layer',objNode)
end



-- 在场景中加入单个节点，该节点不纳入管理体系
--todo 重构去掉该方法 zjb 2015年6月11日
function SceneManager:addToScene(objNode)
    self:addToPopupLayer(objNode)
--    nZOrder = nZOrder or 1000
--    self:getScene():addChild(objNode)
end

-- 注册按键响应
function SceneManager:registEventListenerKeyboard(objScene) 
    self.isEnding = self.isEnding or false 
    local function onKeyReleased(keyCode,event)
        local target = event:getCurrentTarget()
        if keyCode == cc.KeyCode.KEY_BACK then 
            local function onOK() 
                cc.Director:getInstance():endToLua()              --退出游戏
            end  
            if not self.isEnding then
                local dlg = MessageDialog:show(i18n_home_is_game_exit,onOK,nil,true)
				local function eventfun(event) 
					if event == 'cleanup' or event == 'exit' then 
						self.isEnding = false
					end
				end
				regNodeEvent(dlg,eventfun)  
                self.isEnding = true
            end
        end
    end 
    local listener = cc.EventListenerKeyboard:create()
    listener:registerScriptHandler(onKeyReleased,cc.Handler.EVENT_KEYBOARD_RELEASED) 
    local eventDispatcher =  cc.Director:getInstance():getEventDispatcher() 
    eventDispatcher:addEventListenerWithSceneGraphPriority(listener,objScene)
end 

-- 使得UI组件在屏幕自适应时靠左对齐(UI组件在设计时按1136X640摆放)
function SceneManager:alignToLeft_1136X640(node)
    local x,y = node:getPosition()
    local dx = REAL_SCREEN_SIZE.width - 1136
    dx = dx / 2
    node:setPosition(cc.p(x - dx,y))
end

-- 使得UI组件在屏幕自适应时靠右对齐(UI组件在设计时按1136X640摆放)
function SceneManager:alignToRight_1136X640(node)
    local x,y = node:getPosition()
    local dx = REAL_SCREEN_SIZE.width - 1136
    dx = dx / 2
    node:setPosition(cc.p(x + dx,y))
end

-- 使得UI组件在屏幕自适应时靠左对齐(UI组件在设计时按960X640摆放)
function SceneManager:alignToLeft_960X640(node)
    local x,y = node:getPosition()
    local dx = REAL_SCREEN_SIZE.width - 960
    dx = dx / 2
    node:setPosition(cc.p(x - dx,y))
end

-- 使得UI组件在屏幕自适应时靠右对齐(UI组件在设计时按960X640摆放)
function SceneManager:alignToRight_960X640(node)
    local x,y = node:getPosition()
    local dx = REAL_SCREEN_SIZE.width - 960
    dx = dx / 2
    node:setPosition(cc.p(x + dx,y))
end


--添加菜单栏控件
function SceneManager:addEdge(edgeview)  
	local function eventfun(event)
        if event == "cleanup" or event == "exit" then 
			for i= 1,#self.arrEdge do 
				if edgeview==self.arrEdge[i] then 
					table.remove(self.arrEdge,i)
					break
				end
			end
        end
    end  
	regNodeEvent(edgeview,eventfun)  
    table.insert(self.arrEdge,edgeview)	
end  


------------------------------------------------------------


